home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 068 (1988-08-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 068 (1988-08-15)(Ossowski, Stefan)(DE)(PD).adf / DMouse / dmouse-handler.c < prev    next >
C/C++ Source or Header  |  1988-06-18  |  9KB  |  349 lines

  1.  
  2. /*
  3.  *  DMOUSE-HANDLER.C        compile 32 bit integers (+L)
  4.  *                AZTEC COMPILATION
  5.  *  18 May 1988
  6.  */
  7.  
  8. #include "dmouse.h"
  9.  
  10. #define IBASE IntuitionBase
  11.  
  12. DMS    *Dms;
  13. struct IntuitionBase *IntuitionBase;
  14. struct GfxBase         *GfxBase;
  15. long             *LayersBase;
  16.  
  17. NS    Ns = {    0, 0, 64, -1, 1, -1, -1, 0, CUSTOMSCREEN|SCREENQUIET };
  18.  
  19. IE *handler();
  20.  
  21. _main()
  22. {
  23.     register DMS *dms;
  24.     IOR  *ior;
  25.     INT addhand;
  26.  
  27.     {
  28.     register PROC *proc = (PROC *)FindTask(NULL);
  29.     proc->pr_ConsoleTask = NULL;
  30.     }
  31.     dms = Dms = FindPort(PORTNAME);
  32.     if (!dms)
  33.     _exit(0);
  34.     dms->Port.mp_Flags = PA_SIGNAL;
  35.     dms->Port.mp_SigBit = AllocSignal(-1);
  36.     dms->Port.mp_SigTask = FindTask(NULL);
  37.     dms->HandTask = dms->Port.mp_SigTask;
  38.     ior = CreateStdIO(&dms->Port);
  39.     IntuitionBase = OpenLibrary("intuition.library", 0);
  40.     GfxBase = OpenLibrary("graphics.library", 0);
  41.     LayersBase = OpenLibrary("layers.library", 0);
  42.  
  43.     if (!IntuitionBase || !GfxBase || !LayersBase)
  44.     goto startupfail;
  45.     addhand.is_Node.ln_Pri = 51;
  46.     addhand.is_Code = (FPTR)handler;
  47.     addhand.is_Data = NULL;
  48.  
  49.     if (OpenDevice("input.device", 0, ior, 0)) {
  50.     goto startupfail;
  51.     } else {
  52.     SCR *scr = NULL;
  53.     uword *SprSavePtr = NULL;
  54.  
  55.     Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  56.     ior->io_Command = IND_ADDHANDLER;
  57.     ior->io_Data = (APTR)&addhand;
  58.     DoIO(ior);
  59.     for (;;) {
  60.         register long sigs = Wait(SBF_C|(1<<dms->Port.mp_SigBit));
  61.         if (sigs & (1 << dms->Port.mp_SigBit)) {
  62.         register MSG *msg;
  63.         while (msg = GetMsg(&dms->Port)) {
  64.             switch((long)msg->mn_Node.ln_Name) {
  65.             case REQ_SCREENON:
  66.             if (scr)
  67.                 CloseScreen(scr);
  68.             scr = NULL;
  69.             break;
  70.             case REQ_SCREENOFF:
  71.             if (scr) {
  72.                 ScreenToFront(scr);
  73.             } else {
  74.                 if (scr = OpenScreen(&Ns))
  75.                 SetRGB4(&scr->ViewPort, 0, 0, 0, 0);
  76.             }
  77.             break;
  78.             case REQ_MOUSEON:
  79.             if (SprSavePtr) {
  80.                 register COPINIT *ci = GfxBase->copinit;
  81.                 ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
  82.                 ci->sprstrtup[3] = (uword)(long)SprSavePtr;
  83.                 SprSavePtr = NULL;
  84.             }
  85.             break;
  86.             case REQ_MOUSEOFF:
  87.             {
  88.                 register COPINIT *ci = GfxBase->copinit;
  89.                 if (!SprSavePtr)
  90.                 SprSavePtr = (uword *)((ci->sprstrtup[1] << 16) | ci->sprstrtup[3]);
  91.                 ci->sprstrtup[1] = (ulong)dms->NoSprData >> 16;
  92.                 ci->sprstrtup[3] = (uword)(long)dms->NoSprData;
  93.             }
  94.             break;
  95.             case REQ_DOCMD:
  96.             {
  97.                 long fh = Open("nil:", 1006);
  98.                 Execute(dms->Cmd, NULL, fh);
  99.                 if (fh)
  100.                 Close(fh);
  101.             }
  102.             break;
  103.             }
  104.             FreeMem(msg, msg->mn_Length);
  105.         }
  106.         }
  107.         if (sigs & SBF_C)
  108.         break;
  109.     }
  110.     Forbid();
  111.     ior->io_Command = IND_REMHANDLER;
  112.     ior->io_Data = (APTR)&addhand;
  113.     DoIO(ior);
  114.     Permit();
  115.     CloseDevice(ior);
  116.     {
  117.         register MSG *msg;
  118.         while (msg = GetMsg(&dms->Port))
  119.         FreeMem(msg, msg->mn_Length);
  120.     }
  121.     if (scr)
  122.         CloseScreen(scr);
  123.     if (SprSavePtr) {
  124.         register COPINIT *ci = GfxBase->copinit;
  125.         ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
  126.         ci->sprstrtup[3] = (uword)(long)SprSavePtr;
  127.         SprSavePtr = NULL;
  128.     }
  129.     }
  130.     goto closedown;
  131. startupfail:
  132.     dms->StartupError = 1;
  133.     Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  134.     Wait(SBF_C);
  135. closedown:
  136.     DeleteStdIO(ior);
  137. fail:
  138.     if (IntuitionBase)
  139.     CloseLibrary(IntuitionBase);
  140.     if (GfxBase)
  141.     CloseLibrary(GfxBase);
  142.     if (LayersBase)
  143.     CloseLibrary(LayersBase);
  144.     Forbid();
  145.     Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  146. }
  147.  
  148.  
  149. #asm
  150.         ;    A0 = pointer to event linked list
  151.         ;    A1 = pointer to my data segment
  152.         ;    return new event linked list in D0
  153.  
  154.         public  _CHandler
  155.  
  156. _handler:
  157.         movem.l D2/D3/A0/A1/A4/A6,-(sp)
  158.         jsr     _CHandler
  159.         movem.l (sp)+,D2/D3/A0/A1/A4/A6
  160.         rts
  161.  
  162. #endasm
  163.  
  164. /*
  165.  *  (1) Accellerate mouse movements.
  166.  *  (2) Auto-Select window
  167.  */
  168.  
  169. IE *
  170. CHandler(scr0, scr1, Ev)
  171. IE *Ev;
  172. {
  173.     register IE *ev;
  174.     register DMS *dms;
  175.     static char STimedout;
  176.     static char MTimedout;
  177.     static long STime, MTime;
  178.  
  179.     geta4();
  180.     dms = Dms;
  181.     for (ev = Ev; ev; ev = Ev->ie_NextEvent) {
  182.     switch(ev->ie_Class) {
  183.     case IECLASS_RAWMOUSE:
  184.         /*
  185.          *    Mouse events restore both the screen and mouse pointer.
  186.          */
  187.  
  188.         STime = ev->ie_TimeStamp.tv_secs + dms->STo;
  189.         MTime = ev->ie_TimeStamp.tv_secs + dms->MTo;
  190.         if (STimedout)
  191.         sendrequest(REQ_SCREENON);
  192.         if (MTimedout)
  193.         sendrequest(REQ_MOUSEON);
  194.         STimedout = MTimedout = 0;
  195.  
  196.         /*
  197.          *    Mouse Acceleration
  198.          */
  199.         {
  200.         register short n;
  201.         register short s;
  202.  
  203.         if (dms->Acc != 1) {
  204.             n = ev->ie_X;
  205.             s = 1;
  206.             if (n < 0) {
  207.             n = -n;
  208.             s = -1;
  209.             }
  210.             if (n > dms->AThresh)
  211.             ev->ie_X = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
  212.             n = ev->ie_Y;
  213.             s = 1;
  214.             if (n < 0) {
  215.             n = -n;
  216.             s = -1;
  217.             }
  218.             if (n > dms->AThresh)
  219.             ev->ie_Y = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
  220.         }
  221.         }
  222.  
  223.         /*
  224.          *    Auto Activate and LMB (win/scrn front/bak)
  225.          */
  226.         if (dms->AAEnable | dms->LMBEnable) {
  227.         register LAYER *layer;
  228.  
  229.         Forbid();
  230.         layer = WhichMouseLayer();
  231.         if (dms->LMBEnable && ev->ie_Code == IECODE_RBUTTON && (ev->ie_Qualifier & dms->RQual)) {
  232.             register WIN *win;
  233.             if (layer && (win = (WIN *)layer->Window) && !(win->Flags & BACKDROP) && (win->NextWindow || win->WScreen->FirstWindow != win))
  234.             WindowToBack(layer->Window);
  235.             else if (IBASE->FirstScreen)
  236.             ScreenToBack(IBASE->FirstScreen);
  237.             ev->ie_Class = IECLASS_NULL;    /*    remove event    */
  238.         }
  239.         if (layer && layer->Window) {
  240.             if (dms->LMBEnable && ev->ie_Code == IECODE_LBUTTON && layer->ClipRect && layer->ClipRect->Next) {
  241.             /*
  242.              *  Note: Case where it is the 'first' click in a series, where dms->CTime is
  243.              *      garbage, works properly no matter what DoubleClick returns.
  244.              */
  245.             if ((APTR)dms->CWin == layer->Window && DoubleClick(dms->CTime.tv_secs, dms->CTime.tv_micro, ev->ie_TimeStamp.tv_secs, ev->ie_TimeStamp.tv_micro))
  246.                 --dms->CLeft;
  247.             else
  248.                 dms->CLeft = dms->Clicks - 1;
  249.             dms->CTime = ev->ie_TimeStamp;
  250.             dms->CWin = (WIN *)layer->Window;
  251.             if (dms->CLeft == 0) {
  252.                 dms->CLeft = dms->Clicks;
  253.                 WindowToFront(layer->Window);
  254.             }
  255.             }
  256.             if (dms->AAEnable && ev->ie_Code == IECODE_NOBUTTON && !(ev->ie_Qualifier & 0x7000) && layer->Window != IBASE->ActiveWindow)
  257.             ActivateWindow(layer->Window);
  258.         }
  259.         Permit();
  260.         }
  261.         break;
  262.     case IECLASS_RAWKEY:
  263.         /*
  264.          *    Keyboard events will kill the screen timeout but not
  265.          *    the mouse timeout.
  266.          */
  267.         {
  268.         register LAYER *layer;
  269.  
  270.         Forbid();
  271.         layer = WhichMouseLayer();
  272.         if (layer && layer->Window) {
  273.             if (dms->AAEnable && layer->Window != IBASE->ActiveWindow)
  274.             ActivateWindow(layer->Window);
  275.         }
  276.         Permit();
  277.         }
  278.         STime = ev->ie_TimeStamp.tv_secs + dms->STo;
  279.         if (STimedout)
  280.         sendrequest(REQ_SCREENON);
  281.         STimedout = 0;
  282.         if (ev->ie_Code == dms->Code && ev->ie_Qualifier == dms->Qual) {
  283.         sendrequest(REQ_DOCMD);
  284.         ev->ie_Class = IECLASS_NULL;    /*  remove event    */
  285.         }
  286.         break;
  287.     case IECLASS_TIMER:
  288.         /*
  289.          *    On a timer event, if timeout has occured execute the operation
  290.          *    and reset the timeout.    Note that this will cause continuous
  291.          *    timeouts every STo and MTo seconds... required because at any
  292.          *    time Intuition might turn the mouse back on or open a screen or
  293.          *    something and I want the blanker's to work in the long run.
  294.          */
  295.         {
  296.         register long old;
  297.         if (dms->STo && (old = STime - ev->ie_TimeStamp.tv_secs) < 0) {
  298.             STime = ev->ie_TimeStamp.tv_secs + dms->STo + 10;
  299.             STimedout = 1;
  300.             if (old > -10)
  301.             sendrequest(REQ_SCREENOFF);
  302.         }
  303.         if (dms->MTo && (old = MTime - ev->ie_TimeStamp.tv_secs) < 0) {
  304.             MTime = ev->ie_TimeStamp.tv_secs + dms->MTo + 1;
  305.             MTimedout = 1;
  306.             if (old > -10)
  307.             sendrequest(REQ_MOUSEOFF);
  308.         }
  309.         }
  310.         break;
  311.     }
  312.     }
  313.     return(Ev);
  314. }
  315.  
  316.  
  317. sendrequest(req)
  318. long req;
  319. {
  320.     register MSG *msg = AllocMem(sizeof(MSG), MEMF_PUBLIC);
  321.  
  322.     if (msg) {
  323.     msg->mn_Node.ln_Name = (char *)req;
  324.     msg->mn_ReplyPort = NULL;
  325.     msg->mn_Length = sizeof(MSG);
  326.     PutMsg(&Dms->Port, msg);
  327.     }
  328. }
  329.  
  330. LAYER *
  331. WhichMouseLayer()
  332. {
  333.     register struct IntuitionBase *ib = IBASE;
  334.     register LAYER *layer = NULL;
  335.     register SCR *scr = ib->FirstScreen;
  336.  
  337.     for (scr = ib->FirstScreen; scr; scr = scr->NextScreen) {
  338.     register short mousey = ib->MouseY;
  339.     if (!(scr->ViewPort.Modes & LACE))
  340.         mousey >>= 1;
  341.     if (layer = WhichLayer(&scr->LayerInfo, ib->MouseX, mousey - scr->ViewPort.DyOffset))
  342.         break;
  343.     if (mousey >= scr->ViewPort.DyOffset)
  344.         break;
  345.     }
  346.     return(layer);
  347. }
  348.  
  349.